﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Gallio.Framework;

namespace DotNetNuke.Tests.UI.WatiN.BuildVerification
{
    using System.IO;

    using Common;
    using Common.WatiNObjects;

    using MbUnit.Framework;

    using Utilities;
    using System.Text.RegularExpressions;

    [TestFixture]
    [DependsOn(typeof(InstallTests))]
    [DependsOn(typeof(UpgradeTests))]
    [DependsOn(typeof(LoginTests))]
    [DependsOn(typeof(HostSettingsTests))]
    public class NewsletterTests : BVTBase
    {
        #region Test Setup and TearDown

        [SetUp]
        public void SetUp()
        {
            SetUpTest();
        }

        [TearDown]
        public void TearDown()
        {
            TearDownTest();
        }

        #endregion

        #region Tests
        [Test]
        [CsvData(ResourcePath = "TestData.InstallList.csv", HasHeader = true)]
        [CsvData(ResourcePath = "TestData.UpgradeList.csv", HasHeader = true)]
        public void Host_User_Can_Send_To_RegisteredUsers(string version, string type)
        {
            if (type.Equals("UpgradeOnly"))
            {
                TestLog.WriteLine("This test has not been run on an installation site.");
                Assert.IsTrue(true);
            }
            else if (type.Equals("InstallOnly"))
            {
                TestLog.WriteLine("This test has not been run on an upgraded site.");
                Assert.IsTrue(true);
            }
            else
            {
                string capturePath = CapturePath + @"\NewslettersTests\HostUserCanSendToRegisteredUsers\";
                if (!Directory.Exists(capturePath))
                {
                    Directory.CreateDirectory(capturePath);
                }
                WebConfigManager.UpdateConfig(PhysicalPath);
                var homePage = new WatiNBase(ieInstance, SiteURL, DatabaseName);
                var loginPage = new LoginPage(homePage);
                try
                {
                    loginPage.LoginUser(TestUsers.Host.UserName, TestUsers.Host.Password);
                    //Assert.IsFalse(homePage.PageContainsErrors());

                    ieInstance.GoTo(SiteURL + "/tabid/16/portalid/0/Default.aspx");
                    if (homePage.PageContainsErrors())
                    {
                        //Take a screen Capture
                        ieInstance.CaptureWebPageToFile(CapturePath + "/ErrorOnHostSettingsPage.jpg");
                        TestLog.WriteHighlighted("WARNING:");
                        TestLog.WriteLine("An error occurred on the Host Settings Page, view the corresponding screen shot and exception text log for more information on the error. ");

                        //Record any recent exceptions in the log
                        ieInstance.GoTo(SiteURL + "/Host/SQL.aspx");
                        HostSQLPage SQLPage = new HostSQLPage(homePage);
                        SQLPage.CheckForRecentExceptionsWriteToFile(CapturePath + "HostSettingsExceptions.txt", SiteType.Equals("Qualifier"));

                        //Continue the test
                        ieInstance.GoTo(SiteURL + "/tabid/16/portalid/0/Default.aspx");
                    }
                    HostSettingsPage hostSettings = new HostSettingsPage(homePage);
                    hostSettings.SetSMTPSettings("test@dnn.com", "localhost");

                    //Add a user for testing 
                    ieInstance.GoTo(SiteURL + "/Admin/UserAccounts.aspx");
                    //Assert.IsFalse(homePage.PageContainsErrors());
                    UserPage userPage = new UserPage(homePage);
                    userPage.AddUser(TestUsers.User1.UserName, TestUsers.User1.Password, TestUsers.User1.FirstName, TestUsers.User1.LastName, TestUsers.User1.EmailAddress, TestUsers.User1.DisplayName);
                    System.Threading.Thread.Sleep(1000);
                    if (homePage.PageContainsErrors())
                    {
                        //Take a screen Capture
                        ieInstance.CaptureWebPageToFile(CapturePath + "/ErrorOnUserAccountsPage.jpg");
                        TestLog.WriteHighlighted("WARNING:");
                        TestLog.WriteLine("An error occurred on the User Accounts Page, view the corresponding screen shot and exception text log for more information on the error. ");

                        //Record any recent exceptions in the log
                        ieInstance.GoTo(SiteURL + "/Host/SQL.aspx");
                        HostSQLPage SQLPage = new HostSQLPage(homePage);
                        SQLPage.CheckForRecentExceptionsWriteToFile(CapturePath + "UserAccountsExceptions.txt", SiteType.Equals("Qualifier"));

                        //Continue the test
                        ieInstance.GoTo(SiteURL + "/Admin/UserAccounts.aspx");
                    }
                    System.Threading.Thread.Sleep(1000);
                    SiteMenu menu = new SiteMenu(homePage);
                    if (!version.Equals("") && UpgradeVersion < new Version("5.0.0"))
                    {
                        ieInstance.GoTo(SiteURL + "/Admin/BulkEmail.aspx");
                    }
                    else
                    {
                        ieInstance.GoTo(SiteURL + "/Admin/Newsletters.aspx");
                    }
                    System.Threading.Thread.Sleep(1500);
                    // Delete The Email files
                    homePage.DeleteFilesInTestEmails();


                    //var additionalEmailsField = "philip.beadle@dnncorp.com";
                    var fromAddressField = "test@dnncorp.com";
                    var replyToField = "reply@dnncorp.com";
                    var subjectField = "New Newsletter Subject";
                    var contentField = "This is the Newsletter";

                    var newsletterPage = new NewsletterPage(homePage);
                    newsletterPage.CheckRoleCheckBoxByName("Registered Users");
                    //newsletterPage.AdditionalEmailsField.Value = additionalEmailsField;
                    newsletterPage.FromAddressField.Value = fromAddressField;
                    newsletterPage.ReplyToField.Value = replyToField;
                    newsletterPage.SubjectField.Value = subjectField;
                    newsletterPage.SelectRadioButtonByName(ieInstance, "BASIC");
                    newsletterPage.MessageTabLink.Click();
                    newsletterPage.ContentTextBox.Value = contentField;
                    newsletterPage.SendButton.ClickNoWait();
                    System.Threading.Thread.Sleep(1000);
                    if (homePage.PageContainsErrors())
                    {
                        //Take a screen Capture
                        ieInstance.CaptureWebPageToFile(CapturePath + "/ErrorOnNewsletterPage.jpg");
                        TestLog.WriteHighlighted("WARNING:");
                        TestLog.WriteLine("An error occurred on the Newsletter Page, view the corresponding screen shot and exception text log for more information on the error. ");

                        //Record any recent exceptions in the log
                        ieInstance.GoTo(SiteURL + "/Host/SQL.aspx");
                        HostSQLPage SQLPage = new HostSQLPage(homePage);
                        SQLPage.CheckForRecentExceptionsWriteToFile(CapturePath + "NewsLetterPageExceptions.txt", SiteType.Equals("Qualifier"));
                    }

                    Assert.IsTrue(Directory.GetFiles(TestEmailPath).Length > 0);
                    System.Threading.Thread.Sleep(1500);
                    String emailFileName = null;
                    string emailContent = null;
                    int userFilePosition = 0;
                    int adminPosition = 0;
                    for (int i = 0; i < Directory.GetFiles(TestEmailPath).Length; i++)
                    {
                        emailFileName = Directory.GetFiles(TestEmailPath)[i];
                        emailContent = File.ReadAllText(emailFileName);
                        if (!emailContent.Contains("X-Receiver: " + fromAddressField) && !emailContent.Contains("X-Receiver: test@dnn.com") && !emailContent.Contains("X-Receiver: " + TestUsers.Admin.Email))
                        {
                            if (version == "")
                            {
                                userFilePosition = i;
                            }
                            else if (emailContent.Contains(TestUsers.User1.EmailAddress))
                            {
                                userFilePosition = i;
                            }
                        }
                        else if (emailContent.Contains("X-Receiver: " + TestUsers.Admin.Email))
                        {
                            adminPosition = i;
                        }
                    }

                    emailFileName = Directory.GetFiles(TestEmailPath)[userFilePosition];
                    emailContent = File.ReadAllText(emailFileName);

                    String fromLine = FindFromLineUsingRegex(emailContent, emailFileName);
                    String toLine = FindToLineUsingRegex(emailContent, emailFileName);
                    String replyToLine = FindReplyToUsingRegex(emailContent, emailFileName);
                    String contentLine = FindContentUsingRegex(emailContent, contentField, emailFileName);

                    Assert.IsTrue(fromLine.Contains(fromAddressField), fromLine);
                    Assert.IsTrue(toLine.Contains(TestUsers.User1.EmailAddress), toLine);
                    Assert.IsTrue(replyToLine.Contains(replyToField));
                    Assert.IsTrue(contentLine.Contains(contentField), contentLine);

                    //Now check the admin received a newsletter
                    emailFileName = Directory.GetFiles(@TestEnvironment.TestEmailPath)[adminPosition];
                    emailContent = File.ReadAllText(emailFileName);

                    fromLine = FindFromLineUsingRegex(emailContent, emailFileName);
                    toLine = FindToLineUsingRegex(emailContent, emailFileName);
                    replyToLine = FindReplyToUsingRegex(emailContent, emailFileName);
                    contentLine = FindContentUsingRegex(emailContent, contentField, emailFileName);

                    Assert.IsTrue(fromLine.Contains(fromAddressField), fromLine);
                    Assert.IsTrue(toLine.Contains(TestUsers.Admin.Email), toLine);
                    Assert.IsTrue(replyToLine.Contains(replyToField));
                    Assert.IsTrue(contentLine.Contains(contentField), contentLine);

                    // Delete The EmailAddress files
                    homePage.DeleteFilesInTestEmails();
                }
                catch (Exception e)
                {
                    if (!e.ToString().Contains("AssertionFailureException"))
                    {
                        ieInstance.CaptureWebPageToFile(capturePath + "Exception.jpg");
                        Assert.IsTrue(false, "An Exception Occured during the test, view the screen shot for more information. " + System.Environment.NewLine + e.ToString());
                    }
                    else
                    {
                        throw e;
                    }
                }
            }
        }


        #endregion

        #region Private Methods

        private String FindFromLineUsingRegex(string emailContent, string emailFileName)
        {
            string fromLineRegex = @"From: .*\..*";
            Match match = Regex.Match(@emailContent, @fromLineRegex);
            Assert.IsTrue(match.Success, "Could not find from Line! Looking in file: " + emailFileName);
            String fromLine = match.Value;
            return fromLine;
        }

        private String FindToLineUsingRegex(string emailContent, string emailFileName)
        {
            string toLineRegex = @"To: .*\..*";
            Match match = Regex.Match(@emailContent, @toLineRegex);
            Assert.IsTrue(match.Success, "Could not find to Line! Looking in file: " + emailFileName);
            String toLine = match.Value;
            return toLine;
        }
        
        private String FindReplyToUsingRegex(string emailContent, string emailFileName)
        {
            string replyToLineRegex = @"Reply-To: .*\..*";
            Match match = Regex.Match(@emailContent, @replyToLineRegex);
            Assert.IsTrue(match.Success, "Could not find Reply-To Line! Looking in file: " + emailFileName);
            String replyToLine = match.Value;
            return replyToLine;
        }

        private String FindContentUsingRegex(string emailContent, string content, string emailFileName)
        {
            string contentLineRegex = @content + ".*";
            Match match = Regex.Match(@emailContent, @contentLineRegex);
            Assert.IsTrue(match.Success, "Could not find content Line! Looking in file: " + emailFileName);
            String contentLine = match.Value;
            return contentLine;
        }

        #endregion

    }



}
